package Components
{
	import Helpers.TaskLink;
	
	import Model.Story;
	import Model.Task;
	
	import Providers.SimpleDragEvent;
	
	import flash.geom.Point;
	
	import mx.binding.utils.ChangeWatcher;
	import mx.collections.ArrayCollection;
	import mx.containers.Canvas;
	import mx.containers.Panel;
	import mx.events.CollectionEvent;
	import mx.events.CollectionEventKind;

	public class DevWorkspace extends Panel
	{
		protected var linkLayer:Canvas;
		
		private var _stories:ArrayCollection;
		[Bindable]
		public function get stories():ArrayCollection
		{
			return _stories;
		}
		public function set stories(val:ArrayCollection):void
		{
			if(_stories)
			{
				_stories.removeEventListener(CollectionEvent.COLLECTION_CHANGE, storiesChanged);
				for each(var story:Story in _stories)
					removeStory(story);
			}
			_stories = val;
			if(_stories)
			{
				_stories.addEventListener(CollectionEvent.COLLECTION_CHANGE, storiesChanged);
				for each(story in _stories)
					addStory(story);
			}
		}
		
		public function DevWorkspace()
		{
			super();
			addEventListener(SimpleDragEvent.DRAG_ENTER, function(evt:SimpleDragEvent):void
			{
				if(evt.Victim is PostIt || evt.Victim is Card || evt.Victim is CommentPanel)
					evt.Accept = true;	
			});
			addEventListener(SimpleDragEvent.DRAG_DROP, function(evt:SimpleDragEvent):void
			{
				if(evt.Victim is PostIt)
				{
					PostIt(evt.Victim).task.x = evt.Victim.x;
					PostIt(evt.Victim).task.y = evt.Victim.y;
					if(PostIt(evt.Victim).task.isAttached)
					{
						PostIt(evt.Victim).task.isAttached = false;
						addLink(PostIt(evt.Victim));
					}
				}
				if(evt.Victim is Card)
				{
					Card(evt.Victim).story.x = evt.Victim.x;
					Card(evt.Victim).story.y = evt.Victim.y;
				}
			});
		}
		
		protected override function createChildren():void
		{
			super.createChildren();
			if(!linkLayer)
			{
				linkLayer = new Canvas();
				linkLayer.percentWidth = 100;
				linkLayer.percentHeight = 100;
				addChildAt(linkLayer,0);
			}
		}
		protected function storiesChanged(evt:CollectionEvent):void
		{
			if(evt.kind == CollectionEventKind.ADD)
				addStory(Story(evt.items[0]));
			else if(evt.kind == CollectionEventKind.REMOVE)
				removeStory(Story(evt.items[0]));
		}
		protected function tasksChanged(evt:CollectionEvent):void
		{
			if(evt.kind == CollectionEventKind.ADD)
				addTask(Task(evt.items[0]));
			else if(evt.kind == CollectionEventKind.REMOVE)
				removeTask(Task(evt.items[0]));					
		}
		
		protected function addStory(story:Story):void
		{
			//add the card to the workspace
			var card:Card = new Card();
			card.story = story;
			if(story.x == 0 && story.y == 0)
				positionNewCard(card);
			addChild(card);
			
			story.tasks.addEventListener(CollectionEvent.COLLECTION_CHANGE, tasksChanged);
			//add all un-attached tasks for this card
			for each(var task:Task in story.tasks)
				addTask(task);
		}
		protected function removeStory(story:Story):void
		{
			//remove the card from the workspace
			for(var j:int=0; j<numChildren; j++)
				if(getChildAt(j) is Card)
					if(Card(getChildAt(j)).story == story)
						removeChildAt(j);
			
			//find and remove all detached tasks
			story.tasks.removeEventListener(CollectionEvent.COLLECTION_CHANGE, tasksChanged);
			for each(var task:Task in story.tasks)
				removeTask(task);
		}
		
		protected function addTask(task:Task):void
		{
			if(!task.isAttached)
			{
				var postIt:PostIt = new PostIt();
				postIt.task = task;
				addChild(postIt);
				addLink(postIt);
			}
		}
		protected function removeTask(task:Task):void
		{
			if(!task.isAttached)
				for(var i:int=0; i<numChildren; i++)
					if(getChildAt(i) is PostIt)
						if(PostIt(getChildAt(i)).task == task)
						{
							removeLink(PostIt(getChildAt(i)));
							removeChildAt(i);
						}
		}
		
		public function getCardForTask(task:Task):Card
		{
			for(var i:int=0; i<numChildren; i++)
				if(getChildAt(i) is Card)
					for each(var cur:Task in Card(getChildAt(i)).story.tasks)
						if(cur == task)
							return Card(getChildAt(i));
			return null;
		}
		
		protected function addLink(postIt:PostIt):void
		{
			var tl:TaskLink = new TaskLink();
			tl.postIt = postIt;
			tl.workspace = this;
			linkLayer.addChild(tl);
			var cw:ChangeWatcher = ChangeWatcher.watch(postIt, ["task","IsAttached"], function():void
			{
				if(postIt.task.isAttached)
				{
					linkLayer.removeChild(tl);
					cw.unwatch();
				}
			});
		}
		protected function removeLink(postIt:PostIt):void
		{
			for(var i:int=0; i<linkLayer.numChildren; i++)
			{
				var link:TaskLink = linkLayer.getChildAt(i) as TaskLink;
				if(link.postIt == postIt)
					linkLayer.removeChild(link);
			}
		}
		
		protected function positionNewCard(card:Card):void
		{
			var current:Point = new Point(0,0);
			var spotFilled:Boolean = true;
			while(spotFilled)
			{
				spotFilled = false;
				for(var i:int=0; i<numChildren; i++)
					if(current.x == getChildAt(i).x && current.y == getChildAt(i).y)
					{
						spotFilled = true;
						break;
					}
				if(spotFilled)
					current = new Point(current.x + 15, current.y + 25);
				else
				{
					card.story.x = current.x;
					card.story.y = current.y;
				}
			}
		}
	}
}